# -*- coding: utf-8 -*-
from django.views.decorators.csrf import csrf_exempt
from django.template import Context, loader, RequestContext
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
from content_adm.models import Student, Course, Mark, Competence, CompinCrs, MarkforComp, Profession, CompforProf, Software
from operator import itemgetter
from content_adm.functions import *
from content_adm.syncdb_lms import update_local_database
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase import ttfonts
from reportlab.lib.units import inch


# представление для вызова первой страницы с аутентификацией
def main(request):
	update_result = update_local_database()
	return render(request, 'content_adm/main.html')

# представление для второй страницы с уточнением оценок студента
def detail(request):
	try:
		stud_mail = request.POST['stud_mail']
		student = Student.objects.get(mail = stud_mail)					# пытаемся считать из базы запись по студенту через введенный mail

	except:
		login = request.POST['login']
		password = request.POST['passw']
		try:
			student = Student.objects.get(fb_login = login)
		except:
#			student = openIDauthentication(login,password)				# вызов функции аутентификации через OpenID - заглушка
	try:
		course_list = Course.objects.all().filter(control_type = True)	# получаем список курсов, по которым есть экзамен
		mark_list = []													# список оценок, существующих в базе
		empty_mark_list = []											# список оценок, которые будет предложено зполнить пользователю
		ne_course_list = []

		# выделяем из общего множества курсов только за те, за которыми закреплена хотя бы одна компетенция
		for course in course_list:
			cc_list = CompinCrs.objects.filter(crs = course.crs_id)
			if len(cc_list) > 0:
				ne_course_list.append(course)
				
	
		for course in ne_course_list:
			try:
				mark = course.mark_set.get(stud=student.stud_id)		# добавление записи о сущетсвующей оценке
				mark_list.append(mark)

			except (Mark.DoesNotExist):
				empty_mark_list.append({'crs': course.crs_name})		# добавление записи об отсутствии оценки по курсу
			
		for mark in mark_list:											# конвертация оценок для их классического (2-5) представления
			mark = convert(mark)

		return render(request, 'content_adm/details.html', {'ider': student,'mark_list': mark_list, 'empty_mark_list': empty_mark_list})																		# отрисовка страницы с оценками студента
	except:
		return render(request, 'content_adm/main_error.html')			# в случае ввода неправильного mail - повторное приглашение
			
# представление для проведения анализа профессий/компетенций
def results(request, stud_id):
	student = Student.objects.get(pk = stud_id)			
	course_list = Course.objects.all().filter(control_type = True)
	competence_list = Competence.objects.all()
	ne_course_list = []

	# получаем список курсов, по которым нужно сохранить итоговые оценки	
	for course in course_list:
		cc_list = CompinCrs.objects.filter(crs = course.crs_id)
		if len(cc_list) > 0:
			ne_course_list.append(course)

	# сохраняем оценки из формы в базу программы
	get_save_marks(ne_course_list, student, request)
	
	calculate_list = []					# список словарей, получившийся по результатам обсчета каждой компетенции. список полей:
										# comp_id - идентификатор компетенции
										# hours_way - что нужно использовать при выставлении оценки (часы - True, коэф. - False)
										# result_k - оценка, полученная через коэффициенты
										# comp_hours - общее количество взвешенных часов по компетенции
										# result_hours - оценка, полученная через часы
	
	for competence in competence_list:		
		check_factor = False
		crs_competences_list = CompinCrs.objects.filter(cmpt = competence.cmpt_id)
		total_competence_result_k = 0
		hours_mark_list = []
		total_competence_hours = 0
		for crs_competence in crs_competences_list:

			course = crs_competence.crs
			
			mark_result	= 0.0									# итоговая взвешенная оценка по компетенции в курсе
			mf = 0												# итоговая оценка по курсу
			ma = 0												# средняя оценка по курсу
			mc = 0												# оценка за компетенцию в курсе
			
			try:
				mark_course_object = Mark.objects.get(crs = course.crs_id, stud = student.stud_id)
				mf = mark_course_object.mark_final
				ma = mark_course_object.mark_avg
			except:
				mf = 0
				ma = 0

			try:
				mark_comp_object = MarkforComp.objects.get(cc = crs_competence.cc_id, stud = student.stud_id)
				mc = mark_comp_object.mark_comp
			except:
				mc = 0
			try:
				ef = crs_competence.eff_factor						# коэффициент влияния курса на изучение компетенции
			except:
				ef = 0
			percent = crs_competence.percent					# процент для компетенции от общего времени курса
			hlec = course.hours_lect							# часы лекций
			hprac = course.hours_pract							# часы семинаров
			hlab = course.hours_lab								# часы лабораторных работ
			hself = course.hours_self							# часы самостоятельной работы
			cproj = course.crs_project							# наличие курсового проекта по предмету

			# подсчитываем взвешенное количество часов для данной компетенции в курсе
			sub_hours = hours_count(hlec,hprac,hlab,hself,cproj,percent)	

			if ef == 0:											# проверяем наличие коэффициента влияние курса на навык
				check_factor = True								# в случае отсутствия коэффициента влияния переключаем триггер check_factor
			
			mark_result = mark_count(mf,ma,mc)					# считаем суммарную оценку с учетом итоговой, средней и "компетентной"
			
			total_competence_hours += sub_hours 				# прибавляем к общему количеству часов по компетенции, количество часов по 
																# компетенции из данного курса
			if not check_factor:
				result_k = (mark_result * ef) / 100				# делаем оценку для компетенции в курсе через коэффициент методиста
				total_competence_result_k += result_k			# прибавляем предыдущую оценку к общей оценке за компетенцию

			hours_mark_list.append((mark_result, sub_hours))	# формируем список кортежей для создания взвещенной оценки с учетом
																# часов		

			# выходим из цикла для компетенции во всех курсах

		# считаем взвешенную оценку для компетенции с учетом всех курсов для нее
		total_competence_result_hours = total_mark_count(total_competence_hours,hours_mark_list)

			
		dict_element = {'cmpt_id': competence.cmpt_id, 'cmpt_short_name': competence.cmpt_short_name, 'hours_way': check_factor, 'result_k': total_competence_result_k, 'comp_hours': total_competence_hours, 'result_hours': total_competence_result_hours}
		calculate_list.append(dict_element)
	
	# считаем максимальное количество часов на одну компетенцию
	max_hours = max_hours_count(calculate_list)

	# считаем оценки по всем компетенциям
	comp_mark_calculate_result = comp_mark_calculate(calculate_list, max_hours)
	final_calculate_list = comp_mark_calculate_result.get('final_calculate_list')
	clen = comp_mark_calculate_result.get('clen')
	
	# считаем оценки по все профессиям
	profession_list_calculate_return = profession_list_calculate(final_calculate_list)
	resume_list = profession_list_calculate_return.get('resume_list')					# перечень окончательных результатов по профессиям
	plen = profession_list_calculate_return.get('plen')									# количество профессий с оценкой больше 0

	mp_profession = profession_list_calculate_return.get('mp_profession')				# инф-ия по профессии с самой высокой оценкой

# формируем информации по професси с самой высокой оценкой для отображения
	mp = calculate_best_profession(mp_profession)			

	plen = plen*100 + 60																# кол-во профессий с оценкой больше 0
	clen = clen*100 + 30																# кол-во компетенций с оценкой больше 0
		
	return render(request, 'content_adm/results.html', {'ider': student, 'final_calculate_list': final_calculate_list, 'resume_list': resume_list, 'clen': clen, 'plen': plen, 'mp': mp})


# представление для формирования окончательного резюме
def resume(request, length):
	resume_dict = get_all_info(request, length)
	
	if resume_dict['resume_type'] == u'1':											# в html форме
		return render(request, 'content_adm/resume.html', {'r_d': resume_dict})
	else:																			# в pdf форме
		response = HttpResponse(content_type='application/pdf')			
		response['Content-Disposition'] = 'attachment; filename="CV.pdf"'

		p = canvas.Canvas(response)
		p = prepare_canvas(p, resume_dict)											# вызов функции прорисовки pdf
		p.showPage()
		p.save()
		return response	
